﻿using Paas.Pioneer.Domain.Shared.Dto.Input;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using OfficeOpenXml;
using Paas.Pioneer.Admin.Core.HttpApi.Client.ServiceProxies;
using Volo.Abp.Application.Services;
using Volo.Abp;
using Paas.Pioneer.Domain.Shared.Dto.Output;
using Paas.Pioneer.IOTNetworkCard.Domain.ImportNetworkCard;
using Paas.Pioneer.IOTNetworkCard.Application.Contracts.ImportNetworkCard.Dto.Output;
using Paas.Pioneer.IOTNetworkCard.Application.Contracts.ImportNetworkCard.Dto.Input;
using Paas.Pioneer.IOTNetworkCard.Application.Contracts.ImportNetworkCard;
using Paas.Pioneer.IOTNetworkCard.Domain.NetworkCard;
using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using Paas.Pioneer.IOTNetworkCard.Domain.CarrierOperator;
using Volo.Abp.ObjectMapping;

namespace Paas.Pioneer.IOTNetworkCard.Application.ImportNetworkCard
{
    /// <summary>
    /// 导入网卡记录服务
    /// </summary>
    public class ImportNetworkCardService : ApplicationService, IImportNetworkCardService
    {
        private readonly IImportNetworkCardRepository _importNetworkCardRepository;
        private readonly IDictionaryServiceProxy _dictionaryServiceProxy;
        private readonly INetworkCardRepository _networkCardRepository;
        private readonly ICarrierOperatorRepository _carrierOperatorRepository;

        /// <summary>
        /// 构造函数
        /// </summary>
        public ImportNetworkCardService(IImportNetworkCardRepository importNetworkCardRepository,
            IDictionaryServiceProxy dictionaryServiceProxy, INetworkCardRepository networkCardRepository,
            ICarrierOperatorRepository carrierOperatorRepository)
        {
            _importNetworkCardRepository = importNetworkCardRepository;
            _dictionaryServiceProxy = dictionaryServiceProxy;
            _networkCardRepository = networkCardRepository;
            _carrierOperatorRepository = carrierOperatorRepository;
        }

        /// <summary>
        /// 查询导入网卡记录
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        public async Task<GetImportNetworkCardOutput> GetAsync(Guid id)
        {
            var result = await _importNetworkCardRepository.GetAsync(p => p.Id == id, x =>
                new GetImportNetworkCardOutput()
                {
                    ImportSumCount = x.ImportSumCount,
                    ImportSuccessCount = x.ImportSuccessCount,
                    CarrierOperatorId = x.CarrierOperatorId,
                    CarrierOperatorPackageDictionaryId = x.CarrierOperatorPackageDictionaryId,
                    NetworkCardDictionaryId = x.NetworkCardDictionaryId,
                    Remark = x.Remark,
                    CreationTime = x.CreationTime,
                    Id = x.Id,
                });
            return result;
        }

        /// <summary>
        /// 查询分页导入网卡记录
        /// </summary>
        /// <param name="input">入参</param>
        /// <returns></returns>
        public async Task<Page<GetImportNetworkCardPageListOutput>> GetPageListAsync(
            PageInput<GetImportNetworkCardPageListInput> input)
        {
            var data = await _importNetworkCardRepository.GetResponseOutputPageListAsync(x =>
                new GetImportNetworkCardPageListOutput
                {
                    ImportSumCount = x.ImportSumCount,
                    ImportSuccessCount = x.ImportSuccessCount,
                    CarrierOperatorId = x.CarrierOperatorId,
                    CarrierOperatorPackageDictionaryId = x.CarrierOperatorPackageDictionaryId,
                    NetworkCardDictionaryId = x.NetworkCardDictionaryId,
                    Remark = x.Remark,
                    CreationTime = x.CreationTime,
                    Id = x.Id,
                }, input: input);


            if (data.Total == 0)
            {
                return data;
            }

            var _carrierOperatorList =
                await _carrierOperatorRepository.GetListAsync(
                    x => data.List.Select(x => x.CarrierOperatorId).Contains(x.Id),
                    s => new
                    {
                        s.Id,
                        s.Name
                    });

            var carrierOperatorDictionaryList =
                await _dictionaryServiceProxy.GetListAsync(data.List.Select(x => x.CarrierOperatorPackageDictionaryId)
                    .Distinct());
            var networkCardDictionaryList =
                await _dictionaryServiceProxy.GetListAsync(data.List.Select(x => x.NetworkCardDictionaryId).Distinct());

            foreach (var item in data.List)
            {
                item.CarrierOperatorDictionaryName = carrierOperatorDictionaryList
                    ?.FirstOrDefault(x => x.Id == item.CarrierOperatorPackageDictionaryId)?.Name;

                item.NetworkCardDictionaryName = networkCardDictionaryList
                    ?.FirstOrDefault(x => x.Id == item.NetworkCardDictionaryId).Name;

                item.CarrierOperatorName =
                    _carrierOperatorList.FirstOrDefault(x => x.Id == item.CarrierOperatorId)?.Name;
            }

            return data;
        }

        /// <summary>
        /// 新增导入网卡记录
        /// </summary>
        /// <param name="input">入参</param>
        /// <returns></returns>
        public async Task AddAsync(AddImportNetworkCardInput input)
        {
            FileInfo file = new FileInfo(input.file);
            if (file == null)
            {
                throw new BusinessException("文件错误，请重写上传");
            }

            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
            using ExcelPackage package = new ExcelPackage(file);
            if (package.Workbook.Worksheets == null || package.Workbook.Worksheets.Count == 0)
            {
                throw new BusinessException("文件错误，请重写上传");
            }

            ExcelWorksheet worksheet = package.Workbook.Worksheets.FirstOrDefault();
            //获取表格的列数和行数
            Debug.Assert(worksheet != null, nameof(worksheet) + " != null");
            int rowCount = worksheet.Dimension.Rows;
            int colCount = worksheet.Dimension.Columns;
            var networkCardEntityList = new List<NetworkCardEntity>();
            var inserttworkCardEntityList = new List<NetworkCardEntity>();
            var importFailDtos = new List<ImportFailDto>();
            for (int row = 2; row <= rowCount; row++)
            {
                var iccidstr = worksheet.Cells[row, 1].Value?.ToString();
                var accessPhoneStr = worksheet.Cells[row, 1].Value?.ToString();
                if (iccidstr.IsNullOrEmpty() || accessPhoneStr.IsNullOrEmpty())
                {
                    importFailDtos.Add(new ImportFailDto()
                    {
                        ICCID = iccidstr,
                        AccessPhone = accessPhoneStr,
                        Remark = "温馨提醒：表格中存在空数据，跳过该条，请知悉"
                    });
                }

                // 判断新增的表格里面是否有重复数据
                if (networkCardEntityList.Any(x => x.ICCID == iccidstr && x.AccessPhone == accessPhoneStr))
                {
                    importFailDtos.Add(new ImportFailDto()
                    {
                        ICCID = iccidstr,
                        AccessPhone = accessPhoneStr,
                        Remark = "温馨提醒：表格中存在重复的数据，跳过该条，请知悉"
                    });
                    continue;
                }

                networkCardEntityList.Add(new NetworkCardEntity()
                {
                    ICCID = iccidstr,
                    AccessPhone = accessPhoneStr,
                    CarrierOperatorId = input.CarrierOperatorId,
                    CarrierOperatorPackageDictionaryId = input.CarrierOperatorPackageDictionaryId,
                    NetworkCardDictionaryId = input.NetworkCardDictionaryId,
                    IsPollingCard = input.isPollingCard,
                });
            }

            var nclist = await _networkCardRepository
                .GetListAsync(p => networkCardEntityList.Select(x => x.ICCID).Contains(p.ICCID), s => new
                {
                    s.ICCID,
                    s.AccessPhone,
                    s.CarrierOperatorId
                });

            // 导入成功卡数
            var importSuccessCount = 0;
            foreach (var newitem in networkCardEntityList)
            {
                if (nclist.Any(x => x.ICCID == newitem.ICCID && x.AccessPhone == newitem.AccessPhone))
                {
                    importFailDtos.Add(new ImportFailDto()
                    {
                        ICCID = newitem.ICCID,
                        AccessPhone = newitem.AccessPhone,
                        Remark = "此数据已经存在，导入失败"
                    });
                    continue;
                }

                inserttworkCardEntityList.Add(newitem);
                importSuccessCount += 1;
            }

            if (importSuccessCount == 0)
            {
                throw new BusinessException("插入的网卡数据已经去存在，请重新编辑插入");
            }

            var importNetworkCard = ObjectMapper.Map<AddImportNetworkCardInput, ImportNetworkCardEntity>(input);
            importNetworkCard.ImportSumCount = rowCount - 1;
            importNetworkCard.ImportSuccessCount = importSuccessCount;

            if (importFailDtos.Count > 0)
            {
                importNetworkCard.Remark = JsonSerializer.Serialize(importFailDtos);
            }

            importNetworkCard = await _importNetworkCardRepository.InsertAsync(importNetworkCard);
            inserttworkCardEntityList.ForEach(x => x.ImportCardId = importNetworkCard.Id);
            await _networkCardRepository.InsertManyAsync(inserttworkCardEntityList);
        }

        /// <summary>
        /// 新增单卡网卡记录
        /// </summary>
        /// <param name="input">入参</param>
        /// <returns></returns>
        public async Task AddSingleCard(AddSingleNetworkCardInput input)
        {
            if (await _networkCardRepository.AnyAsync(p =>
                    p.ICCID == input.ICCID && p.AccessPhone == input.AccessPhone))
            {
                throw new BusinessException("插入的网卡数据已经去存在，请重新编辑插入");
            }

            var importNetworkCard = ObjectMapper.Map<AddSingleNetworkCardInput, ImportNetworkCardEntity>(input);
            importNetworkCard.ImportSumCount = 1;
            importNetworkCard.ImportSuccessCount = 1;
            importNetworkCard = await _importNetworkCardRepository.InsertAsync(importNetworkCard);

            var networkCardEntity = ObjectMapper.Map<AddSingleNetworkCardInput, NetworkCardEntity>(input);
            networkCardEntity.ImportCardId = importNetworkCard.Id;
            await _networkCardRepository.InsertAsync(networkCardEntity);
        }

        /// <summary>
        /// 修改导入网卡记录
        /// </summary>
        /// <param name="input">入参</param>
        /// <returns></returns>
        public async Task UpdateAsync(UpdateImportNetworkCardInput input)
        {
            var entity = await _importNetworkCardRepository.GetAsync(input.Id);
            if (entity?.Id == Guid.Empty)
            {
                throw new BusinessException("数据不存在！");
            }

            ObjectMapper.Map(input, entity);
            await _importNetworkCardRepository.UpdateAsync(entity);
        }

        /// <summary>
        /// 删除导入网卡记录
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        public async Task DeleteAsync(Guid id)
        {
            await _importNetworkCardRepository.DeleteAsync(m => m.Id == id);
        }

        /// <summary>
        /// 批量删除导入网卡记录
        /// </summary>
        /// <param name="ids">主键集合</param>
        /// <returns></returns>
        public async Task BatchSoftDeleteAsync(IEnumerable<Guid> ids)
        {
            await _importNetworkCardRepository.DeleteAsync(x => ids.Contains(x.Id));
        }
    }
}